package com.ruoyi.system.service.impl;

import cn.hutool.json.JSONUtil;

import com.alibaba.fastjson2.JSON;
import com.google.gson.Gson;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.domain.entity.*;
import com.ruoyi.system.domain.vo.ChildVo;

import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.IXunFeiService;
import com.ruoyi.system.util.AudioSplitter.WavMillisecondSplitter;
import com.ruoyi.system.util.xfyun.sign.LfasrSignature;
import com.ruoyi.system.util.xfyun.utils.HttpUtil;
import com.ruoyi.system.util.xfyun.yuyin.EnhancedParser;
import org.apache.commons.lang.StringEscapeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.*;
import java.security.SignatureException;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

@Service
public class XunFei implements IXunFeiService {

    @Autowired
    private AiRecordingChildMapper aiRecordingChildMapper;
    @Autowired
    private AiRecordingMainMapper aiRecordingMainMapper;
    @Autowired
    private SystemFileMapper systemFileMapper;
    @Autowired
    private DeepSeekClient deepSeekClient;
    @Autowired
    private AiRecordingChildServiceImpl aiRecordingChildService;
    @Autowired
    private SysDictDataMapper sysDictDataMapper;

    private static final String HOST = "https://raasr.xfyun.cn";
    private static String AUDIO_FILE_PATH;
    private static final String appid = "d43862bc";
    private static final String keySecret = "51178714c9af08bf153fc77065112666";





    private static String FENDUAN="## 定位\n" +
            "你是加易加公司的专业的中英双语文字处理专家，帮助整理与客户交流记录\n" +
            "\n" +
            "## **核心能力**\n" +
            "1. **对话起止识别**\n" +
            "   - 精准识别中文场景中用户发起的对话起始标记（如「您好」「好久不见」「又见面了」「最近怎么样」等）\n" +
            "   - 可靠检测对话结束标记（如「再联系」「再见」「那先这样」「我再去看看」等）\n" +
            "   - 说话方式、谈话内容、语境发生明显变化\n" +
            "   \n" +
            "2. **智能分段逻辑**\n" +
            "   - 当连续出现新称呼起始语时自动创建新段落\n" +
            "   - 保持原有对话时序完整性\n" +
            "   - 对无法识别的片段保持原样并特殊标注\n" +
            "\n" +
            "3. **交互对象标注**\n" +
            "   - 自动提取对话对象称呼（如「王总监」「Dr.Smith」）\n" +
            "   - 生成段落标题模板：【与{称呼}的对话】\n" +
            "\n" +
            "\n" +
            "## **知识储备**\n" +
            "1. 中英文商务场景种称呼匹配模式\n" +
            "2. 跨文化交际常见结束语库\n" +
            "3. 对话间隙特征数据集\n" +
            "\n" +
            "## ** 输入规范**\n" +
            "输入的内容为一个列表的JSON格式，列表中每一个元素都是一个字典，有两个键，键\"content\"内是一句交流的内容，键\"id\"内是该语句所在索引\n" +
            "## ** 输出规范**\n" +
            "以 JSON 的形式输出，只输出段落开始语句的id\n" +
            "```json\n" +
            "[0,10,17]\n" +
            "```\n" +
            "\n" +
            "以下为用户输入内容";

    private static String HOTWORD="Baograin|Fresilo|Fresilo S|ADA TMR|MoistMax|Antimold JM|Antimold J35|Antimold J40|\n" +
            "Antimold J50|Antimold J60|Donal|ToxinClean Ⅰ|ToxinClean Ⅱ|ToxinClean Ⅲ|Fepro P|Fepro 1000|Salstop|Salvator|Swemmy 600|Swemmy 1500|Zeroxy|Fepro L|Tasty|Optim|Vitacid|Megacid|\n" +
            "Extramet|Extramet S|Mesto 60|Courea|Coda|\n" +
            "Butyplus|Butysmart|VB Plus|Gutpro|Gutclean|GutcleanⅠ|GutcleanⅡ|Cotan|Tanbo|Extragut|Essen Ⅰ|Essen Ⅱ|Phytomed|ADA Allicin|GML|Gutmax|Joymax|Germclean|Power|Spow|Calfacid L|\n" +
            "Calfacid S|Aqual L|Puracid|Fepro-FA|Freshco|Medos|超级酸S|乐味酸|克霉灵J50|六乐酸|防霉剂|克霉灵JD|\n" +
            "克霉灵J|畅乐葆|超级酸FF|易加酸|克霉灵|克霉灵JM|酸霸A|大蒜素|鲜活U500|酸圈圈FLD|乐味酸H|维泽慕 A1|乐多酸|惠酸I型|\n" +
            "维肠乐Ⅱ|四甲酸一铵|易鲜宝|克霉先F|月桂酸单甘脂|意赛多纷|乐味酸S|酸圈圈FS|乳清酸|克霉消|硫醚沙星|美味酸|维泽慕|超级酸|绿诺|奶甜香302|\n" +
            "改水1号|畜科细素|抗氧宝|吉乐酸|乐味酸P|果奶香301|克霉灵A|甲酸|丙酸|甲酸钠|苯甲酸|甲酸钙|苯甲酸钠|\n" +
            "富马酸|磷酸|氯化钙|无水柠檬酸|一水柠檬酸|双乙酸钠|丙酸钙|加易加|addeasy|超甜易加|sweeteasy|优尼特|unite";


     @Override
    public  String xunfeiUtil(String path,Long mainId,Long fileId,String language, String  segmented,Long costomerId, Date time) throws Exception {
        String result = uploadUtil(path,language);
        String jsonStr = StringEscapeUtils.unescapeJavaScript(result);
        String orderId = String.valueOf(JSONUtil.getByPath(JSONUtil.parse(jsonStr), "content.orderId"));

         AiRecordingMain aiRecordingMain=new AiRecordingMain();
         aiRecordingMain.setId(mainId);
         aiRecordingMain.setOrderId(orderId);
//         aiRecordingMain.setStatus("2");
         aiRecordingMainMapper.updateAiRecordingMain(aiRecordingMain);

        getResultUtil(orderId,mainId,fileId,segmented,costomerId,time);
        return  orderId;
    }


//    public static void main(String[] args) throws SignatureException, FileNotFoundException {
//        HashMap<String, Object> map = new HashMap<>(16);
//        File audio = new File("C:\\Users\\jyjkf\\Desktop\\456.wav");
//        String fileName = audio.getName();
//        long fileSize = audio.length();
//        map.put("appId", appid);
//        map.put("fileSize", fileSize);
//        map.put("fileName", fileName);
//        map.put("duration", "200");
//        map.put("roleType", 1);
//        map.put("language", "cn");
//        LfasrSignature lfasrSignature = new LfasrSignature(appid, keySecret);
//        map.put("signa", lfasrSignature.getSigna());
//        map.put("ts", lfasrSignature.getTs());
//        map.put("hotWord", HOTWORD);
//
//
//
////        map.put("callbackUrl", '/getXunFeiResult');
//
//        String paramString = HttpUtil.parseMapToPathParam(map);
////        System.out.println("upload paramString:" + paramString);
//        String url = HOST + "/v2/api/upload" + "?" + paramString;
//        System.out.println("upload_url:" + url);
//        String response = HttpUtil.iflyrecUpload(url, new FileInputStream(audio));
//        System.out.println("upload response:" + response);
//    }


    public  String uploadUtil(String path,String language) throws SignatureException, FileNotFoundException {
        HashMap<String, Object> map = new HashMap<>(16);
        File audio = new File(path);
        String fileName = audio.getName();
        long fileSize = audio.length();
        map.put("appId", appid);
        map.put("fileSize", fileSize);
        map.put("fileName", fileName);
        map.put("duration", "200");
        map.put("roleType", 1);
//        语种类型：默认 cn
        map.put("language", language);
//        map.put("eng_vad_mdn",2);
        LfasrSignature lfasrSignature = new LfasrSignature(appid, keySecret);
        map.put("signa", lfasrSignature.getSigna());
        map.put("ts", lfasrSignature.getTs());
//        System.out.println(  HOTWORD.toString());
        SysDictData hotWordDict= sysDictDataMapper.selectDictDataByTypeOne("xunfei_hotword");
        String promptWords=   hotWordDict.getRemark();
        map.put("hotWord", promptWords);
        String paramString = HttpUtil.parseMapToPathParam(map);
        String url = HOST + "/v2/api/upload" + "?" + paramString;
        System.out.println("upload_url:" + url);
        String response = HttpUtil.iflyrecUpload(url, new FileInputStream(audio));
        System.out.println("upload response:" + response);
        return response;
    }
    private static String usingUUID() {
        UUID randomUUID = UUID.randomUUID();
        return randomUUID.toString().replaceAll("-", "");
    }

    public  String getResultUtil(String orderId,Long mainId,Long fileId, String  segmented,Long customerId, Date time) throws Exception {
        HashMap<String, Object> map = new HashMap<>(16);
        map.put("orderId", orderId);
        LfasrSignature lfasrSignature = new LfasrSignature(appid, keySecret);
        map.put("signa", lfasrSignature.getSigna());
        map.put("ts", lfasrSignature.getTs());
        map.put("appId", appid);
        map.put("resultType", "transfer,predict");
        String paramString = HttpUtil.parseMapToPathParam(map);
        String url = HOST + "/v2/api/getResult" + "?" + paramString;
        System.out.println("\nget_result_url:" + url);
        while (true) {
            System.out.println(url.toString());
            String response = HttpUtil.iflyrecGet(url);
            Gson gson = new Gson();
            JsonParse jsonParse = gson.fromJson(response, JsonParse.class);
//            todo
//            System.out.println("讯飞接口返回结果-存在问题的地方---:" + jsonParse.toString());
            if (jsonParse.content != null && jsonParse.content.orderInfo != null && jsonParse.content.orderInfo.status != null && (jsonParse.content.orderInfo.status == 4 || jsonParse.content.orderInfo.status == -1)) {
                System.out.println("订单完成:");
                List<EnhancedParser.Segment> segmentList= EnhancedParser.parseUtil(response);
                AiRecordingMain aiRecording=new AiRecordingMain();
                aiRecording.setOrderId(orderId);
              String path=  systemFileMapper.selectSystemFileById(fileId).getPath();
                List<String> speakerList=new ArrayList<>();
                AtomicInteger i= new AtomicInteger();
                AtomicReference<Long> childZero= new AtomicReference<>();
                segmentList.forEach(seg->{
                    if (!speakerList.contains(seg.getSpeaker())){
                          speakerList.add(seg.getSpeaker());
                    }
                     AiRecordingChild recordingChild = new AiRecordingChild();
                    recordingChild.setCreateTime(new Date());
                    recordingChild.setMainId(mainId);
                    String bg=  (seg.getStart()+"").split("ms")[0];
                    String eg=  (seg.getEnd()+"").split("ms")[0];
                    recordingChild.setBg(Long.parseLong(bg));
                    recordingChild.setEg(Long.parseLong(eg));
                    recordingChild.setRl(seg.getSpeaker());
                    recordingChild.setTake(recordingChild.getEg()-recordingChild.getBg());
                    String randomString = usingUUID();
                    File inputFile = new File(path);
                    String newFilePath=RuoYiConfig.getProfile()+ "/"+randomString+".wav";
                    File outputFile = new File(newFilePath);
                    // 示例：从 1000 毫秒（1 秒）到 3000 毫秒（3 秒）分割
                    WavMillisecondSplitter.splitWavByMilliseconds(inputFile, outputFile, Long.parseLong(bg), Long.parseLong(eg));
                    SystemFile systemFile=new SystemFile();
                    systemFile.setPath(newFilePath);
                    systemFile.setCreateTime(new Date());
                    systemFile.setAddress("/profile/"+randomString+".wav");
                    systemFile.setFileType(".wav");
                    systemFileMapper.insertSystemFile(systemFile);
                    recordingChild.setFileId(systemFile.getId());
                    recordingChild.setTranscript(seg.getContent());
                    String wt = seg.getContent().trim();
                    if (wt.equals("nasa.") ||wt.equals("NAna.") ||wt.equals("NASA.") ||wt.equals("NASA,") || wt.equals("NASA") ||  wt.equals("NANA") ||  wt.equals("NA") ||  wt.equals("SA")  ){
                        recordingChild.setDelFlag("1");
                    }
                    aiRecordingChildMapper.insertAiRecordingChild(recordingChild);
                    if (i.get() ==0){
                        childZero.set(recordingChild.getId());
                    }
                    i.set(i.get() + 1);
                });
                AiRecordingMain aiRecordingMain=new AiRecordingMain();
                aiRecordingMain.setId(mainId);
                aiRecordingMain.setStatus("2");
                aiRecordingMainMapper.updateAiRecordingMain(aiRecordingMain);
                getDeepSeek(mainId,segmented, childZero.get(),customerId,time);
                return response;
            } else {
//                System.out.println("进行中...，状态为:" + jsonParse.content.orderInfo.status);
                System.out.println("讯飞接口返回进行中...返回信息:::"+jsonParse.toString());
                //建议使用回调的方式查询结果，查询接口有请求频率限制
                Thread.sleep(30000);
            }
        }
    }
    @Override
    public  String getDeepSeek(Long mainId, String  segmented,Long childZero,Long customerId, Date time) throws InterruptedException {
                 AiRecordingChild recordingChild=new AiRecordingChild();
                 recordingChild.setMainId(mainId);
                 List<AiRecordingChild> aiRecordingChildList= aiRecordingChildMapper.selectAiRecordingChildList(recordingChild);
                 List<ChildVo> duanList=new ArrayList<>();
                 aiRecordingChildList.forEach(record->{
                     ChildVo childVo=new ChildVo();
                     childVo.setId(record.getId());
                     childVo.setContent(record.getTranscript());
                     duanList.add(childVo);
                 });
                 String json = JSON.toJSONString(duanList);
                AiRecordingMain aiRecordingMain=new AiRecordingMain();
                aiRecordingMain.setId(mainId);
                if (segmented.equals("true")){
                    String response = deepSeekClient.deepseekUtil(FENDUAN+json);
                    if (response.contains("以下是输出结果")){
                        response=  response.split("以下是输出结果")[1];
                    }
                    System.out.println("deepseek返回结果"+response);
                    aiRecordingMain.setRangeStrs(response.replaceAll("json", "").
                            replace("`","").replace("[", "").replace("]", "").replace(":", "").replace("：", "").replaceAll("\\s", ""));
                }else{
                    aiRecordingMain.setRangeStrs(childZero+"");
                }
               aiRecordingMain.setSegmented(segmented);
               aiRecordingMain.setStatus("3");
                aiRecordingMainMapper.updateAiRecordingMain(aiRecordingMain);

                if (customerId!=null && time!=null){
                    AiRecordingChild aiRecordingChild=new AiRecordingChild();
                    aiRecordingChild.setMainId(mainId);
                    List<AiRecordingDuan> list = aiRecordingChildService.selectRecordDuanVo(aiRecordingChild);
                    list.get(0).setCustomerId(customerId);
                    list.get(0).setTime(time);
                    AiRecordingMain aiRecordingMain1=new AiRecordingMain();
                    aiRecordingMain1.setId(mainId);
                    aiRecordingMain1.setAiRecordingDuanList(list);
                    List<AiDeepseekSpokesman> aiDeepseekSpokesmanList=new ArrayList<AiDeepseekSpokesman>();
                    list.get(0).getAiRecordingChildList().forEach(child->{
                        AiDeepseekSpokesman aiDeepseekSpokesman=new AiDeepseekSpokesman();
//                        aiDeepseekSpokesman.setDuanId();
                        aiDeepseekSpokesman.setMainId(mainId);
//                        aiDeepseekSpokesman.setBatchId();
                        aiDeepseekSpokesman.setChildId(child.getId());
                        aiDeepseekSpokesmanList.add(aiDeepseekSpokesman);
                    });

                    list.get(0).setAiDeepseekSpokesmanList(aiDeepseekSpokesmanList);
                    aiRecordingChildService.updateAiRecordingChildDuan(aiRecordingMain1);
                }
                 return "getDeepSeek执行结束";
    }

    class JsonParse {
        Content content;
    }

    class Content {
        OrderInfo orderInfo;
    }

    class OrderInfo {
        Integer status;
    }
}
